package com.zl.learning.io.nio.Chat;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;

/**
 * Created by zhaolei on 2017/5/2.
 */
public class DatagramChannelServerDemo {
    private int port = 9975;
    DatagramChannel channel;
//    private Charset charset = Charset.forName("UTF-8");
    private Charset charset = StandardCharsets.UTF_8;
    private Selector selector = null;

    public DatagramChannelServerDemo() throws IOException {
        try {
            selector = Selector.open();
            channel = DatagramChannel.open();
        } catch (IOException e) {
            selector = null;
            channel = null;
            System.out.println("超时");
        }
        System.out.println("服务器启动");
    }

    public ByteBuffer encode(String str){
        return charset.encode(str);
    }

    public String decode(ByteBuffer bb){
        return charset.decode(bb).toString();
    }

    public void service() throws IOException{
        if(channel == null || selector == null) return;
        channel.configureBlocking(false);
        channel.socket().bind(new InetSocketAddress(port));
        channel.register(selector, SelectionKey.OP_READ);

        while (selector.select()>0){
            System.out.println("有新channel加入");
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey key = null;
                try {
                    key = iterator.next();
                    iterator.remove();

                    if(key.isReadable()){
                        reveice(key);
                    }
                    if(key.isWritable()){
                        //send(key);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    try {
                        if(key!=null){
                            key.cancel();
                            key.channel().close();
                        }
                    }catch (ClosedChannelException cex){
                        cex.printStackTrace();
                    }
                }
            }
        }
    }

    synchronized public void reveice(SelectionKey key) throws IOException {
        if(key == null) return;
        DatagramChannel sc = (DatagramChannel) key.channel();
        StringBuilder content = new StringBuilder();
        ByteBuffer buf = ByteBuffer.allocate(1024);
        buf.clear();
        SocketAddress address = sc.receive(buf);
        String clientAddress = address.toString().replace("/","").split(":")[0];
        String clientPost = address.toString().replace("/","").split(":")[1];

        buf.flip();
        while(buf.hasRemaining()){
            buf.get(new byte[buf.limit()]);
            content.append(new String(buf.array()));
        }
        buf.clear();

        System.out.println("接收:"+ content.toString().trim());
        ByteBuffer buf2 = ByteBuffer.allocate(65507);
        buf2.clear();
        buf2.put("消息推送内容".getBytes());
        buf2.flip();
        channel.send(buf2,new InetSocketAddress(clientAddress,Integer.parseInt(clientPost)));
    }

    int y=0;

    public void send(SelectionKey key){
        if(key == null) {
            return;
        }
        DatagramChannel sc = (DatagramChannel) key.channel();
        try {
            sc.write(ByteBuffer.wrap("aaa".getBytes()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("send2()"+(++y));
    }

    public void sendFile(SelectionKey key){
        if(key == null) return;
        ByteBuffer buff = (ByteBuffer) key.attachment();
        SocketChannel sc = (SocketChannel) key.channel();
        String data = decode(buff);
        if(data.contains("get")) return;
        String subStr = data.substring(data.indexOf(" "),data.length());
        System.out.println("截取之后的字符串是 "+subStr);
        FileInputStream fileInput = null;
        try {
            fileInput = new FileInputStream(subStr);
            FileChannel fileChannel = fileInput.getChannel();
            fileChannel.transferTo(0,fileChannel.size(),sc);
            fileChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                assert fileInput != null;
                fileInput.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException {
        new DatagramChannelServerDemo().service();
    }
}
